package io.unicorn.modules.water.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.unicorn.modules.sys.dao.SysDictDao;
import io.unicorn.modules.sys.entity.SysDictEntity;
import io.unicorn.modules.sys.entity.SysUserEntity;
import io.unicorn.modules.sys.shiro.ShiroUtils;
import io.unicorn.modules.water.dao.*;
import io.unicorn.modules.water.entity.*;
import io.unicorn.modules.water.service.TAreaInfoService;
import io.unicorn.modules.water.service.TUniinfoWService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.unicorn.common.utils.PageUtils;
import io.unicorn.common.utils.Query;
import io.unicorn.modules.water.service.TAccountManageService;


@Service("tAccountManageService")
public class TAccountManageServiceImpl extends ServiceImpl<TAccountManageDao, TAccountManageEntity> implements TAccountManageService {
    @Autowired
    private TModeTypeServiceImpl modeTypeService;

    @Autowired
    private TModeTypeDao tModeTypeDao;
    @Autowired
    private TAreaInfoDao tAreaInfoDao;
    @Autowired
    private TUniinfoWDao tUniinfoWDao;
    @Autowired
    private SysDictDao sysDictDao;
    @Autowired
    private TDevicesTypeDao tDevicesTypeDao;
    @Autowired
    private TAreaInfoService areaInfoService;
    @Autowired
    private TUniinfoWService uniinfoWService;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String key   = (String)params.get("key");
        String value = (String)params.get("value");

        String deptId = (String)params.get("dept");
        Map<String , Object> queryMap = new HashMap<>();

        if(StringUtils.isNotBlank(deptId) && StringUtils.isNotEmpty(deptId))
        {
            String[] tmp = deptId.split("_");
            switch(tmp.length){
                case 1:
                    //queryMap.put("city_id",tmp[0]);
                    break;
                case 2:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    break;
                case 3:
                    //queryMap.put("city_id",tmp[0]);
                    queryMap.put("area_id",tmp[1]);
                    queryMap.put("unit_w_id",tmp[2]);
                    break;
            }
        }

        //2025.5.31 超期数据关闭查看
        SysUserEntity user = ShiroUtils.getUserEntity();
        Integer intViewData = user.getViewData();

        IPage<TAccountManageEntity> page = this.page(
                new Query<TAccountManageEntity>().getPage(params),
                new QueryWrapper<TAccountManageEntity>()
                        .allEq(queryMap!=null && queryMap.size() > 0, queryMap, false)
                        .like(StringUtils.isNotBlank(value) && StringUtils.isNotBlank(key), key, value)
                        .apply(intViewData != 1,"pro_name not  in (select 小区名称 from [Gather_DB].[dbo].[v_stop_view_data])")
        );

        //2022.1.18 填充名称
        Set<Integer> modeIds = page.getRecords().stream().map(TAccountManageEntity::getModeId).collect(Collectors.toSet());
        if (modeIds.size()>0) {
            List<TModeTypeEntity> modeList = tModeTypeDao.selectList(Wrappers.lambdaQuery(TModeTypeEntity.class).in(TModeTypeEntity::getModeId, modeIds));
            Map<Integer, String> hashMap = modeList.stream().collect(Collectors.toMap(TModeTypeEntity::getModeId, TModeTypeEntity::getModeName));
            page.getRecords().forEach(e -> e.setModeName(hashMap.get(e.getModeId())));
        }

        Set<String> areaIds = page.getRecords().stream().map(TAccountManageEntity::getAreaId).collect(Collectors.toSet());
        if (areaIds.size() > 0) {
            List<TAreaInfoEntity> areaList = tAreaInfoDao.selectList(Wrappers.lambdaQuery(TAreaInfoEntity.class).in(TAreaInfoEntity::getAreaId, areaIds));
            Map<String, String> areaMap = areaList.stream().collect(Collectors.toMap(TAreaInfoEntity::getAreaId, TAreaInfoEntity::getAreaName));
            page.getRecords().forEach(e -> e.setAreaName(areaMap.get(e.getAreaId())));
        }

        Set<Integer> unitIds = page.getRecords().stream().map(TAccountManageEntity::getUnitWId).collect(Collectors.toSet());
        if (unitIds.size()>0) {
            List<TUniinfoWEntity> unitList = tUniinfoWDao.selectList(Wrappers.lambdaQuery(TUniinfoWEntity.class).in(TUniinfoWEntity::getUnitId, unitIds));
            Map<Integer, String> unitMap = unitList.stream().collect(Collectors.toMap(TUniinfoWEntity::getUnitId, TUniinfoWEntity::getUnitName));
            page.getRecords().forEach(e -> e.setUnitName(unitMap.get(e.getUnitWId())));
        }

        /*
        Set<Integer> proTypeIds = page.getRecords().stream().map(TAccountManageEntity::getProTypeId).collect(Collectors.toSet());
        List<TDevicesTypeEntity> proTypeList = tDevicesTypeDao.selectList(Wrappers.lambdaQuery(TDevicesTypeEntity.class).in(TDevicesTypeEntity::getTypeId, proTypeIds));
        Map<Integer, String> proTypeMap = proTypeList.stream().collect(Collectors.toMap(TDevicesTypeEntity::getTypeId, TDevicesTypeEntity::getTypeName));
        page.getRecords().forEach(e -> e.setProTypeName(proTypeMap.get(e.getProTypeId())));
        */

        return new PageUtils(page);
    }

    @Override
    public PageUtils getClientErrorDataByProcedure(Map<String, Object> params) {
        Integer pageSize = (Integer.parseInt(params.get("limit").toString()));
        Integer currPage = (Integer.parseInt(params.get("page").toString()));

        List<TAccountManageEntity> dataList = baseMapper.execProClientErrorInfo(params);
        //从第几条数据开始
        Integer firstIndex = (currPage - 1) * pageSize;
        //到第几条数据结束
        Integer lastIndex = currPage * pageSize;

        lastIndex = lastIndex > dataList.size() ? dataList.size() : lastIndex;

        return new PageUtils(dataList.subList(firstIndex, lastIndex),dataList.size(),pageSize,currPage);
    }

    //生成导入数据的模板
    @Override
    public byte[] genExcelTemplate(){
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ExcelWriter excelWriter = EasyExcel.write(os).build();

        Set<String> includeColumnFiledNames = new HashSet<String>();
        includeColumnFiledNames.add("proName");
        includeColumnFiledNames.add("desc1");
        includeColumnFiledNames.add("desc2");
        includeColumnFiledNames.add("areaId");
        includeColumnFiledNames.add("unitWId");
        includeColumnFiledNames.add("modeId");
        includeColumnFiledNames.add("proTypeId");
        includeColumnFiledNames.add("deviceCount");
        includeColumnFiledNames.add("sCount");
        includeColumnFiledNames.add("cleanCount");
        includeColumnFiledNames.add("salesCount");
        includeColumnFiledNames.add("desc3");
        includeColumnFiledNames.add("debugerPhone");
        includeColumnFiledNames.add("installerName");
        includeColumnFiledNames.add("desc4");
        includeColumnFiledNames.add("installerPhone");
        includeColumnFiledNames.add("debugerName");
        includeColumnFiledNames.add("desc13");
        includeColumnFiledNames.add("desc5");
        includeColumnFiledNames.add("desc6");
        includeColumnFiledNames.add("desc7");
        includeColumnFiledNames.add("desc8");
        includeColumnFiledNames.add("desc9");
        includeColumnFiledNames.add("desc10");
        includeColumnFiledNames.add("desc11");
        includeColumnFiledNames.add("desc12");
        includeColumnFiledNames.add("desc14");

        List<TAccountManageEntity> listData = baseMapper.selectList(new QueryWrapper<TAccountManageEntity>().eq("pro_name", "xxxx"));
        TAccountManageEntity accountManageEntity = new TAccountManageEntity();
        accountManageEntity.setProName("关键码");
        accountManageEntity.setDeviceCount(0);
        accountManageEntity.setModeId(1);
        accountManageEntity.setProTypeId(0);

        listData.add(accountManageEntity);

        WriteSheet writeSheet = EasyExcel.writerSheet(0, "Sheet1")
                .includeColumnFiledNames(includeColumnFiledNames)
                .head(TAccountManageEntity.class).build();
        excelWriter.write(listData, writeSheet);

        //同时导出字典表
        writeSheet = EasyExcel.writerSheet(1, "区域字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"areaId","areaName"})))
                .head(TAreaInfoEntity.class).build();
        excelWriter.write(tAreaInfoDao.selectList(new QueryWrapper<>()),writeSheet);

        //导出管理所字典
        writeSheet = EasyExcel.writerSheet(2, "管理所字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"unitId","unitName"})))
                .head(TUniinfoWEntity.class).build();
        excelWriter.write(tUniinfoWDao.selectList(new QueryWrapper<>()),writeSheet);

        //采集类型字典
        writeSheet = EasyExcel.writerSheet(3, "采集类型字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"modeId","modeName"})))
                .head(TModeTypeEntity.class).build();
        excelWriter.write(tModeTypeDao.selectList(new QueryWrapper<>()),writeSheet);

        //导出其他字典，统一由系统字典产生
        writeSheet = EasyExcel.writerSheet(4, "水表品牌字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_brand")),writeSheet);

        writeSheet = EasyExcel.writerSheet(5, "安装位置字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_fix_addr")),writeSheet);

        writeSheet = EasyExcel.writerSheet(6, "表拿子字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_rope")),writeSheet);

        writeSheet = EasyExcel.writerSheet(7, "水表类型字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_device_type")),writeSheet);

        writeSheet = EasyExcel.writerSheet(8, "系统类型字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_system_mode")),writeSheet);

        writeSheet = EasyExcel.writerSheet(9, "是否竣工字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_finished")),writeSheet);

        writeSheet = EasyExcel.writerSheet(10, "小区类型字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code","value"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_protype")),writeSheet);

        excelWriter.finish();

        return os.toByteArray();
    }

    @Override
    public List<Map<String, Object>> execProCalDevCount(Map<String, Object> params) {
        return baseMapper.execProCalDevCount(params);
    }

    @Override
    public List<Map <String, Object>> selectViewAccountExceed(Map<String, Object> params){
        return baseMapper.selectViewAccountExceed(params);
    }

    @Override
    public List<Map<String, Object>> selectViewAccountExceedSub(Map<String, Object> params) {
        return baseMapper.selectViewAccountExceedSub(params);
    }

    @Override
    public List<Map<String, Object>> execGetChartData(Map<String, Object> params) {
        return baseMapper.execGetChartData(params);
    }

    @Override
    public List<Map<String, Object>> exeProSynData(Map<String, Object> params) {
        return baseMapper.exeProSynData(params);
    }

    @Override
    public List<Map<String, Object>> exeProSynDataGx(Map<String, Object> params) {
        return baseMapper.exeProSynDataGx(params);
    }

    @Override
    public List<Map<String, Object>> exeAutoProSynData(Map<String, Object> params) {
        return baseMapper.exeAutoProSynData(params);
    }
}
